using Mapster;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using QiAdmin.Core;
using QiAdmin.Core.Services.Log;
using QiAdmin.Core.Services.Token;
using QiAdmin.Entity;
using QiAdmin.Model.Dtos;
using QiAdmin.Model.Dtos.Input;
using QiAdmin.Model.Dtos.Output;
using QiAdmin.Repository.Repository;
using QiAdmin.Service.IService;
using ICacheService = QiAdmin.Core.Services.Cache.ICacheService;

namespace QiAdmin.Service.Service
{
    /// <summary>
    /// TSysDicType Services
    /// </summary>
    public class TSysDictTypeService : BaseService<TSysDictType, TSysDictType_IN, TSysDictType_OUT>, ITSysDictTypeService
    {
        readonly TSysDictTypeRepository _tSysDictTypeRepository;
        readonly TSysDictDataRepository _tSysDictDataRepository;
        readonly ITSysDictDataService _tSysDictDataService;
        public TSysDictTypeService(ILogService logService,
            ITokenService tokenService, ICacheService cacheService, IHttpContextAccessor httpContextAccessor, TSysDictTypeRepository tSysDictTypeRepository, TSysDictDataRepository tSysDictDataRepository, ITSysDictDataService tSysDictDataService) : base(logService, tokenService, cacheService, httpContextAccessor.HttpContext)
        {
            _tSysDictTypeRepository = tSysDictTypeRepository;
            _tSysDictDataRepository = tSysDictDataRepository;
            _tSysDictDataService = tSysDictDataService;
        }

        #region 增删改查-自动生成

        /// <summary>
        /// 创建默认条件
        /// </summary>
        /// <returns></returns>
        public Expressionable<TSysDictType> CreateExp()
        {
            var exp = Expressionable.Create<TSysDictType>();

            return exp;
        }

        /// <summary>
        /// 新增单条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Add(TSysDictType_IN input)
        {
            var model = input.Adapt<TSysDictType>();
            int Id = _tSysDictTypeRepository.InsertReturnIdentity(model);
            _tSysDictDataService.AddDictCache();
            return CommonResult.Convert(Id > 0);
        }

        /// <summary>
        /// 新增多条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult AddRange(List<TSysDictType_IN> input)
        {
            var list = input.Adapt<List<TSysDictType>>();
            var result = _tSysDictTypeRepository.InsertRange(list);
            _tSysDictDataService.AddDictCache();
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Edit(TSysDictType_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);
            var model = input.Adapt<TSysDictType>();
            var result = _tSysDictTypeRepository.UpdateAndIgnore(model, exp.ToExpression());
            _tSysDictDataService.AddDictCache();
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 获取单条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<TSysDictType_OUT> Get(TSysDictType_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);

            var result = _tSysDictTypeRepository.GetFirst(exp.ToExpression()).Adapt<TSysDictType_OUT>();
            return new CommonResult<TSysDictType_OUT>(result);
        }

        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<PageOutput<TSysDictType_OUT>> GetPageList(TSysDictType_IN input)
        {
            var exp = CreateExp();

            exp.AndIF(input.StartQueryTime != DateTime.MinValue, t => t.SysCreateTime >= input.StartQueryTime.Date);
            exp.AndIF(input.EndQueryTime != DateTime.MinValue, t => t.SysCreateTime < input.EndQueryTime.Date.AddDays(1));
            exp.AndIF(!string.IsNullOrEmpty(input.Name), t => t.Name == input.Name);
            exp.AndIF(input.Status == true, t => t.Status == true);

            PageOutput<TSysDictType_OUT> pageOutput = new PageOutput<TSysDictType_OUT>();
            PageModel pageModel = new() { PageIndex = input.PageIndex, PageSize = input.PageSize };
            pageOutput.Data = _tSysDictTypeRepository.GetPageList(exp.ToExpression(), pageModel).Adapt<List<TSysDictType_OUT>>();
            pageOutput.DataCount = pageModel.TotalCount;

            return new CommonResult<PageOutput<TSysDictType_OUT>>(pageOutput);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Remove(TSysDictType_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);

            var result = _tSysDictTypeRepository.Delete(exp.ToExpression());
            _tSysDictDataService.AddDictCache();
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 删除多条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult RemoveRange(List<TSysDictType_IN> input)
        {
            var exp = CreateExp();
            exp.And(t => input.Select(s => s.Id).Contains(t.Id));

            var result = _tSysDictTypeRepository.Delete(exp.ToExpression());
            _tSysDictDataService.AddDictCache();
            return CommonResult.Convert(result);
        }

        #endregion

        public CommonResult AddData(TSysDictType_IN input)
        {
            ITenant tenant = _tSysDictTypeRepository.AsTenant();
            try
            {
                tenant.BeginTran();
                var model = input.Adapt<TSysDictType>();
                int typeId = _tSysDictTypeRepository.InsertReturnIdentity(model, "添加失败");

                if (input.DictDatas != null && input.DictDatas.Count > 0)
                {
                    var datas = input.DictDatas.Adapt<List<TSysDictData>>();
                    datas.ForEach(data => data.TypeId = typeId);
                    _tSysDictDataRepository.InsertRange(datas);
                }
                _tSysDictDataService.AddDictCache();
                tenant.CommitTran();
                return CommonResult.Success;
            }
            catch
            {
                tenant.RollbackTran();
                return CommonResult.Error;
            }

        }

        public CommonResult EditData(TSysDictType_IN input)
        {
            ITenant tenant = _tSysDictTypeRepository.AsTenant();
            try
            {
                tenant.BeginTran();
                var model = input.Adapt<TSysDictType>();
                _tSysDictTypeRepository.UpdateAndIgnore(model);
                var datas = input.DictDatas.Adapt<List<TSysDictData>>();
                var dbData = _tSysDictDataRepository.GetList(t => t.TypeId == input.Id);

                //新增
                var addData = datas.FindAll(s => s.Id == 0);
                _tSysDictDataRepository.InsertRange(addData);

                //编辑
                var editData = datas.FindAll(s => dbData.Exists(d => d.Id == s.Id));
                editData.ForEach(s =>
                {
                    _tSysDictDataRepository.UpdateAndIgnore(s);
                });

                //删除
                var deleteData = dbData.FindAll(s => s.Id != 0 && !datas.Exists(d => d.Id == s.Id));
                _tSysDictDataRepository.DeleteByIds(deleteData.Select(s => (dynamic)s.Id).ToArray());
                _tSysDictDataService.AddDictCache();
                tenant.CommitTran();
                return CommonResult.Success;
            }
            catch
            {
                tenant.RollbackTran();
                return CommonResult.Error;
            }
        }

        public CommonResult RemoveData(List<TSysDictType_IN> input)
        {
            ITenant tenant = _tSysDictTypeRepository.AsTenant();
            try
            {
                tenant.BeginTran();
                _tSysDictTypeRepository.Delete(t => input.Select(s => s.Id).Contains(t.Id));
                _tSysDictDataRepository.Delete(t => input.Select(s => s.Id).Contains(t.TypeId));
                _tSysDictDataService.AddDictCache();
                tenant.CommitTran();
                return CommonResult.Success;
            }
            catch
            {
                tenant.RollbackTran();
                return CommonResult.Error;
            }
        }
    }
}
